package com.nirvana.resolve;

import com.nirvana.config.PluginConfig;
import com.nirvana.convert.CamelCaseConverter;
import com.nirvana.data.DefPropertyData;
import com.nirvana.type.ResolveState;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DefResolver extends AbstractResolver {
    private ResolveState state = ResolveState.NONE;
    private final Pattern commentPattern = Pattern.compile("/\\*+\\s*(.*?)\\s*\\*+/");
    private final Pattern propertyPattern = Pattern.compile("var\\s+(.*?)\\s*:\\s*(.*?)\\s*=\\s*_");
    private final Pattern resolveStringPattern = Pattern.compile("case\\s+\"(.*?)\"\\s*=>\\s*(.*?)\\s*=\\s*(.*?)\\(.*?\\)");
    private final Pattern resolveMapBeanPattern = Pattern.compile("\\s*(.*?)\\s*=\\s*(.*?)\\(mapBean\\)");

    private DefPropertyData lastPropertyData;
    public DefResolver(File file) {
        super(file);
    }

    @Override
    public List<DefPropertyData> resolve() {
        try {
            PluginConfig.getInstance().extendsGroupDef(false);
            List<String> lines = Files.readAllLines(Paths.get(file.toURI()));
            List<DefPropertyData> list = new ArrayList<>();
            Map<String, DefPropertyData> map = new HashMap<>();
            for (int i = lines.size() - 1; i >= 0; i--) {
                String line = lines.get(i);
                if (line.contains("extends") && line.contains("GroupDef")) {
                    PluginConfig.getInstance().extendsGroupDef(true);
                }
                if (Objects.requireNonNull(state) == ResolveState.COMMENT) {
                    state = ResolveState.NONE;
                    if (lastPropertyData != null) {
                        Matcher matcher = commentPattern.matcher(line);
                        // 查找并输出匹配的注释内容
                        if (matcher.find()) {
                            String comment = matcher.group(1);
                            lastPropertyData.setComment(comment);
                        }
                        lastPropertyData = null;
                    }
                } else {
                    Matcher matcher = propertyPattern.matcher(line);
                    if (matcher.find()) {
                        state = ResolveState.COMMENT;
                        String propertyName = matcher.group(1);
                        String propertyType = matcher.group(2);
                        DefPropertyData data = map.getOrDefault(propertyName, null);
                        if (data == null) {
                            data = new DefPropertyData();
                            data.setPropertyName(propertyName);
                            data.setSourceName(CamelCaseConverter.camelToSnakeCase(propertyName));
                        }
                        data.setTypeIndex(propertyType);
                        lastPropertyData = data;
                        list.add(0, data);
                    } else {
                        matcher = resolveStringPattern.matcher(line);
                        if (matcher.find()) {
                            String originName = matcher.group(1);
                            String propertyName = matcher.group(2);
                            String resolveMethod = matcher.group(3);
                            DefPropertyData data = new DefPropertyData();
                            data.setPropertyName(propertyName);
                            data.setSourceName(originName);
                            data.setResolveMethod(resolveMethod);
                            map.put(propertyName, data);
                        } else {
                            matcher = resolveMapBeanPattern.matcher(line);
                            if (matcher.find()) {
                                String propertyName = matcher.group(1);
                                String resolveMethod = matcher.group(2);
                                DefPropertyData data = new DefPropertyData();
                                data.setPropertyName(propertyName);
                                data.setSourceName("");
                                data.setResolveMethod(resolveMethod);
                                map.put(propertyName, data);
                            }
                        }
                    }

                }
            }
            return list;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String getDefClassName() {
        String name = file.getName();
        return name.substring(0, name.lastIndexOf("."));
    }
}
